package com.yenlien.traceyun.usercenter.service;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yenlien.traceyun.usercenter.bean.AppMenuTree;
import com.yenlien.traceyun.usercenter.bean.MenuTree;
import com.yenlien.traceyun.usercenter.dao.*;
import com.yenlien.traceyun.usercenter.entity.*;
import com.yenlien.traceyun.webase.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author: bigwangy@sina.com
 * @create: 2020-03-03
 * @description:
 **/
//@Service
public class ResourceService_bak extends BaseController {

    @Autowired
    private DepartmentResourceDao departmentResourceDao;
    @Autowired
    private ResourceDao resourceDao;

    @Autowired
    private UserResourceDao userResourceDao;

    @Autowired
    private CompanyDao companyDao;

    @Autowired
    private DepartmentDao departmentDao;


    /**
     * 加载当前用户拥有的菜单
     *
     * @param userId
     * @return
     */
    public List<AppMenuTree> findMenusByUserId(String userId) {
        List<MenuTree> userAppMenus = resourceDao.findByUserId(userId);
        Map<App, List<MenuTree>> mapRoot = new HashMap<>();
        Map<String, List<MenuTree>> mapChild = new HashMap<>();
        List<AppMenuTree> result = new ArrayList<>();
        if (userAppMenus != null && userAppMenus.size() > 0) {
            //找到各个app的父节点
            for (MenuTree tree : userAppMenus) {
                //app是否启用
                if (!tree.isAppStatus()) {
                    continue;
                }
                App app = new App();
                app.setId(tree.getAppId());
                app.setName(tree.getAppName());
                app.setUrl(tree.getAppUrl());
                app.setCode(tree.getAppCode());
                //如果是父节点
                if (StringUtils.isEmpty(tree.getParentId())) {
                    if (mapRoot.containsKey(app)) {
                        mapRoot.get(app).add(tree);
                    } else {
                        List<MenuTree> trees = new ArrayList<>();
                        trees.add(tree);
                        mapRoot.put(app, trees);
                    }
                } else {
                    if (mapChild.containsKey(tree.getAppId())) {
                        mapChild.get(tree.getAppId()).add(tree);
                    } else {
                        List<MenuTree> trees = new ArrayList<>();
                        trees.add(tree);
                        mapChild.put(tree.getAppId(), trees);
                    }
                }
            }
            for (Map.Entry<App, List<MenuTree>> entry : mapRoot.entrySet()) {
                recursionAppTree(entry.getValue(), mapChild.get(entry.getKey().getId()));
                result.add(new AppMenuTree(entry.getKey().getId(), entry.getKey().getName(), entry.getKey().getUrl(), entry.getKey().getCode(), entry.getValue()));
            }
        }
        parseTree(result);
        return result;
    }

    /**
     * 进一步解析菜单
     *
     * @param all
     */
    public void parseTree(List<AppMenuTree> all) {

        if (all != null && all.size() > 0) {
            for (AppMenuTree appMenuTree : all) {
                if (appMenuTree.getMenus() != null && appMenuTree.getMenus().size() > 0) {
                    for (MenuTree tree : appMenuTree.getMenus()) {
                        if (tree.isConfigMenu()) {
                            appMenuTree.getConfigMenus().add(tree);
                        } else {
                            appMenuTree.getFlowMenus().add(tree);
                        }
                    }
                }
            }

        }

    }

    /**
     * 通过企业对应的userId查找企业拥有的菜单
     *
     * @param userId
     * @return
     */
    public List<AppMenuTree> findAllMenus(String userId) {
        List<MenuTree> userAppMenus = resourceDao.findByUserId(userId);
        List<MenuTree> appMenus = resourceDao.findAllMenuTree();
        Map<App, List<MenuTree>> mapRoot = new HashMap<>();
        Map<String, List<MenuTree>> mapChild = new HashMap<>();
        List<AppMenuTree> result = new ArrayList<>();
        if (appMenus != null && appMenus.size() > 0) {
            //找到各个app的父节点
            for (MenuTree tree : appMenus) {
                //判断用户chechked;
                if (userAppMenus != null && userAppMenus.size() > 0) {
                    for (MenuTree usertree : userAppMenus) {
                        if (tree.getId().equals(usertree.getId())) {
                            tree.setChecked(true);
                        }
                    }
                }
                App app = new App();
                app.setId(tree.getAppId());
                app.setName(tree.getAppName());
                app.setUrl(tree.getAppUrl());
                app.setCode(tree.getAppCode());
                //如果是父节点
                if (StringUtils.isEmpty(tree.getParentId())) {
                    if (mapRoot.containsKey(app)) {
                        mapRoot.get(app).add(tree);
                    } else {
                        List<MenuTree> trees = new ArrayList<>();
                        trees.add(tree);
                        mapRoot.put(app, trees);
                    }
                } else {
                    if (mapChild.containsKey(tree.getAppId())) {
                        mapChild.get(tree.getAppId()).add(tree);
                    } else {
                        List<MenuTree> trees = new ArrayList<>();
                        trees.add(tree);
                        mapChild.put(tree.getAppId(), trees);
                    }
                }
            }
            for (Map.Entry<App, List<MenuTree>> entry : mapRoot.entrySet()) {
                recursionAppTree(entry.getValue(), mapChild.get(entry.getKey().getId()));
                result.add(new AppMenuTree(entry.getKey().getId(), entry.getKey().getName(), entry.getKey().getUrl(), entry.getKey().getCode(), entry.getValue()));
            }
        }
        parseTree(result);
        return result;
    }

    /**
     * 通过企业对应的userId查找企业拥有的菜单
     *
     * @param userId
     * @param companyUserId
     * @return
     */
    public List<AppMenuTree> findAllMenus(String userId, String companyUserId) {
        List<MenuTree> userAppMenus = resourceDao.findByUserId(userId);
//        List<MenuTree> appMenus = resourceDao.findAllMenuTree();
        List<MenuTree> appMenus = resourceDao.findByUserId(companyUserId);
        return parse(userAppMenus, appMenus);
    }


    /**
     * 通过企业对应的userId查找企业拥有的菜单
     *
     * @param departmentId
     * @return
     */
    public List<AppMenuTree> loadDepartemntMenus(String departmentId) {
        List<MenuTree> userAppMenus = resourceDao.findByDepartmentId(departmentId);
        Company company = companyDao.findById(departmentDao.findById(departmentId).getCompanyId());
        List<MenuTree> appMenus = resourceDao.findByUserId(company.getUserId());
        return parse(userAppMenus, appMenus);
    }

    private List<AppMenuTree> parse(List<MenuTree> userAppMenus, List<MenuTree> appMenus) {
        Map<App, List<MenuTree>> mapRoot = new HashMap<>();
        Map<String, List<MenuTree>> mapChild = new HashMap<>();
        List<AppMenuTree> result = new ArrayList<>();
        if (appMenus != null && appMenus.size() > 0) {
            //找到各个app的父节点
            for (MenuTree tree : appMenus) {
                //判断用户chechked;
                if (userAppMenus != null && userAppMenus.size() > 0) {
                    for (MenuTree usertree : userAppMenus) {
                        if (tree.getId().equals(usertree.getId())) {
                            tree.setChecked(true);
                        }
                    }
                }
                App app = new App();
                app.setId(tree.getAppId());
                app.setName(tree.getAppName());
                app.setUrl(tree.getAppUrl());
                app.setCode(tree.getAppCode());
                //如果是父节点
                if (StringUtils.isEmpty(tree.getParentId())) {
                    if (mapRoot.containsKey(app)) {
                        mapRoot.get(app).add(tree);
                    } else {
                        List<MenuTree> trees = new ArrayList<>();
                        trees.add(tree);
                        mapRoot.put(app, trees);
                    }
                } else {
                    if (mapChild.containsKey(tree.getAppId())) {
                        mapChild.get(tree.getAppId()).add(tree);
                    } else {
                        List<MenuTree> trees = new ArrayList<>();
                        trees.add(tree);
                        mapChild.put(tree.getAppId(), trees);
                    }
                }
            }
            for (Map.Entry<App, List<MenuTree>> entry : mapRoot.entrySet()) {
                recursionAppTree(entry.getValue(), mapChild.get(entry.getKey().getId()));
                result.add(new AppMenuTree(entry.getKey().getId(), entry.getKey().getName(), entry.getKey().getUrl(), entry.getKey().getCode(), entry.getValue()));
            }
        }
        parseTree(result);
        return result;
    }

    /**
     * 加载所有菜单
     *
     * @return
     */
    public List<MenuTree> findMenus(String appId) {
        List<Resource> menus = resourceDao.findAllMenus(appId);
        List<MenuTree> tree = MenuTree.create(resourceDao.findAllRootMenus(appId));
        recursion(tree, menus);
        return tree;
    }

    public Resource add(Resource resource) {
        return resourceDao.save(resource);
    }

    /**
     * 递归操作
     *
     * @param root
     * @param sources
     */
    private void recursion(List<MenuTree> root, List<Resource> sources) {
        if (root != null && root.size() > 0) {
            for (MenuTree tree : root) {
                for (Resource menu : sources) {
                    if (tree.getId().equals(menu.getParentId())) {
                        List<MenuTree> children = tree.getChildren();
                        if (children == null) {
                            children = new ArrayList<MenuTree>();
                            tree.setChildren(children);
                        }
                        children.add(MenuTree.create(menu));
                    }
                }
                recursion(tree.getChildren(), sources);
            }
        }
    }

    /**
     * 递归操作
     *
     * @param root
     * @param sources
     */
    private void recursionAppTree(List<MenuTree> root, List<MenuTree> sources) {
        if (sources == null || sources.size() <= 0) {
            return;
        }
        if (root != null && root.size() > 0) {
            for (MenuTree tree : root) {
                for (MenuTree menu : sources) {
                    if (tree.getId().equals(menu.getParentId())) {
                        List<MenuTree> children = tree.getChildren();
                        if (children == null) {
                            children = new ArrayList<MenuTree>();
                            tree.setChildren(children);
                        }
                        children.add(menu);
                    }
                }
                recursionAppTree(tree.getChildren(), sources);
            }
        }
    }


    /**
     * 根据id查询所有需要删除的resource
     *
     * @param id  需要删除的id
     * @param res 集合
     */

    public void getAllDele(String id, List<Resource> res) {
        List<Resource> resources = resourceDao.findByParentId(id);
        if (resources != null && resources.size() > 0) {
            res.addAll(resources);
            for (Resource resource : resources) {
                getAllDele(resource.getId(), res);
            }
        }
    }

    @Transactional
    public void dete(String id) {
        List<Resource> resources = new ArrayList<>();
        resources.add(resourceDao.getOne(id));
        getAllDele(id, resources);
        //删除
        resourceDao.deleteInBatch(resources);
        List<String> resourceIds = new ArrayList<>();
        for (Resource resource : resources) {
            resourceIds.add(resource.getId());
        }
        //删除关联
        userResourceDao.deleteByResourceId(resourceIds);
    }

    /**
     * @param params
     */
    @Transactional
    public Object setCompanyAppMenu(JSONObject params) {
        //实际是company对应的userId
        String userId = params.getString("userId");
        userResourceDao.deleteByUserId(userId);
        JSONArray menus = params.getJSONArray("menus");
        if (menus != null && menus.size() > 0) {
            List<UserResource> resources = new ArrayList<>();
            for (int i = 0; i < menus.size(); i++) {
                JSONObject menu = menus.getJSONObject(i);
                UserResource resource = new UserResource();
                resource.setAppId(menu.getString("appId"));
                resource.setResourceId(menu.getString("resourceId"));
                resource.setUserId(userId);
                resources.add(resource);
            }
            userResourceDao.saveAll(resources);
            return success(menus.size());
        }
        return success(0);
    }

    /**
     * @param userId
     * @param appId
     * @return
     */
    public boolean hasApp(String userId, String appId) {
        List<UserResource> urs = userResourceDao.findByUserIdAndAppId(userId, appId);
        return urs != null && urs.size() > 0;
    }

    @Transactional
    public void saveDeptMenu(Department department) {
        deleteDeptMenu(departmentResourceDao.findByDepartmentId(department.getId()));
        if (department.getDepartmentResources().size() > 0) {
            for (DepartmentResource departmentMenu : department.getDepartmentResources()) {
                departmentMenu.setDepartmentId(department.getId());
                departmentResourceDao.save(departmentMenu);
            }
        }
    }

    public void deleteDeptMenu(List<DepartmentResource> departmentMenus) {
        departmentResourceDao.deleteAll(departmentMenus);
    }

    public List<DepartmentResource> findByMenu(String id) {
        return departmentResourceDao.findByDepartmentId(id);
    }

    public List<MenuTree> findByAppId(String appId) {
        List<MenuTree> result;
        List<Resource> roots = null;
        List<Resource> children = null;
        List<Resource> resources = resourceDao.findByAppId(appId);
        if (resources != null && resources.size() > 0) {
            roots = new ArrayList<Resource>();
            children = new ArrayList<Resource>();
            for (Resource resource : resources) {
                if (StringUtils.isEmpty(resource.getParentId())) {
                    roots.add(resource);
                } else {
                    children.add(resource);
                }
            }
        }
        result = MenuTree.create(roots);
        this.recursion(result, children);
        return result;
    }

}
